using System.Reflection;
using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Localization;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using OpenIddict.Validation.AspNetCore;
using SageKing.Aspire.ServiceDefaults.Samplers;
using SageKing.Blazor.OpenIdService.Client;
using SageKing.Blazor.OpenIdService.Components;
using SageKing.Blazor.OpenIdService.Extensions;
using SageKing.Blazor.OpenIdService.Services;
using SageKing.OpenIddict.OpenIdService;
using Serilog;
using static NewLife.Remoting.ApiHttpClient;

var builder = WebApplication.CreateBuilder(args);

var configuration = builder.Configuration;
var hostEnvironment = builder.Environment;

//配置 本地 Configuration 目录下json文件
builder.Configuration.AddConfigurationJsonFiles(hostEnvironment);

builder.AddServiceDefaults();

// Add services to the container.

var services = builder.Services;

try
{
    //add SageKing
    builder.Services.AddSageKing(sk =>
    {
        //MediaR
        sk.UseIceMediatR(o => o.MediatRServiceConfiguration += a =>
        {
            a.RegisterServicesFromAssemblies(typeof(Program).Assembly);
        });

        //us log
        sk.UseSageKingLogSerilog();

        //默认配置
        sk.UseSageKingDatabase(o => o.DatabaseOptions += a =>
        {
            configuration.Bind(a);
        });

        //use OpenIddict server 
        sk.UseOpenIddictServer();

        sk.UseOpenIddictClient();

        sk.UseOpenIdResourceWebClientApi();

        sk.UseSageKingAntDesign();

        sk.UseMudBlazorUI();

        //add fluentui-blazor
        sk.UseSKFluentUI();

    }, configuration, hostEnvironment);

    Log.Information("Starting web host");

    builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
    builder.Services.Configure<RequestLocalizationOptions>(options =>
    {
        var supportedCultures = new[] { "zh-CN", "en-US" };
        options.SetDefaultCulture(supportedCultures[0])
             .AddSupportedCultures(supportedCultures)
             .AddSupportedUICultures(supportedCultures);

        options.RequestCultureProviders.Clear(); // 清空默认提供器
                                                 // 添加查询字符串提供器（优先级最高）
        options.RequestCultureProviders.Add(new QueryStringRequestCultureProvider());
        // 可选：添加其他提供器（如 Cookie、Header）
        options.RequestCultureProviders.Add(new CookieRequestCultureProvider());
    });

    // Add services to the container.
    builder.Services.AddRazorComponents()
        .AddInteractiveServerComponents()
        .AddInteractiveWebAssemblyComponents();

    builder.Services.AddCascadingAuthenticationState();
    builder.Services.AddScoped<IdentityUserAccessor>();
    builder.Services.AddScoped<IdentityRedirectManager>();
    //builder.Services.AddScoped<AuthenticationStateProvider, PersistingRevalidatingAuthenticationStateProvider>();

    builder.Services.AddScoped<ICancelSource, CancelSource>();

    builder.Services.AddAuthorization();
    builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();
    builder.Services.AddScoped<CustomAuthenticationService>();
    builder.Services.AddScoped<IAuthorizationHandler, PermissionHandler>();
    //builder.Services.AddScoped<IAuthorizationHandler, MultiRequirementHandler>();
    builder.Services.AddHttpContextAccessor(); // 供Handler访问HttpContext

    // 可以注册一个服务来集中管理API调用
    builder.Services.AddScoped<ApiService>();

    //builder.Services.AddAuthentication(options =>
    //    {
    //        options.DefaultScheme = IdentityConstants.ApplicationScheme;
    //        options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
    //    })
    //    .AddIdentityCookies(); 

    // 注册 CORS 服务
    services.AddCors();
    services.AddAntiforgery(options =>
    {
        options.FormFieldName = "CSRF-TOKEN"; // 表单字段名
        options.HeaderName = "X-CSRF-TOKEN";  // 请求头名
        options.SuppressXFrameOptionsHeader = false;
    });

    //add SwaggerGen
    services.AddSageKingSwaggerGen(configuration);

    // Configure Kestrel
    builder.WebHost.ConfigureKestrel(serverOptions =>
    {
        serverOptions.AddServerHeader = false;
    });

    services.AddModalCRUD();
    ////////////////////////builld
    ///
    var app = builder.Build();

    // Configure the HTTP request pipeline.
    if (app.Environment.IsDevelopment())
    {
        app.UseCors("*");

        app.UseWebAssemblyDebugging();
        app.UseMigrationsEndPoint();

    }
    else
    {
        // 必须放在其他中间件之前
        app.UseForwardedHeaders(new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedFor
        });

        app.UseExceptionHandler("/Error", createScopeForErrors: true);
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        //app.UseHsts(); 反向代理处理 HTTPS
    }

    //use SwaggerGen
    app.UseSageKingSwaggerGen(configuration);

    //app.UseHttpsRedirection(); 反向代理处理 HTTPS

    app.UseStaticFiles();

    app.UseRequestLocalization();

    app.UseRouting();
    //app.UseCors("*");


    app.UseAuthentication(); // 必须在 UseRouting 之后、UseAuthorization 之前
    app.UseAuthorization();

    app.UseAntiforgery();

    //禁用缓存，强制浏览器获取新令牌：
    //app.Use(async (context, next) =>
    //{
    //    context.Response.Headers["Cache-Control"] = "no-cache, no-store";
    //    await next();
    //});

    app.MapRazorComponents<App>()
        .AddInteractiveServerRenderMode()
        .AddInteractiveWebAssemblyRenderMode()
        .AddAdditionalAssemblies(typeof(SageKing.Blazor.OpenIdService.Client.UserInfo).Assembly);

    //Use SageKing
    app.UseSageKingInit(configuration, hostEnvironment);

    // Add additional endpoints required by the Identity /Account Razor components.
    app.MapAdditionalIdentityEndpoints();

    app.MapControllers();
    app.MapDefaultControllerRoute();

    app.MapDefaultEndpoints();

    // Ensure DB migrations
    using (var scope = app.Services.CreateScope())
    {
        var servicesscope = scope.ServiceProvider;
        try
        {
            var migrator = servicesscope.GetRequiredService<IMigrationService>();
            var tmpOptions = new OpenIdServerOptions();
            configuration.Bind(tmpOptions);

            migrator.EnsureMigrationAsync(tmpOptions).GetAwaiter().GetResult();
        }
        catch (Exception ex)
        {
            app.Logger.LogError(ex, "An error occurred while migrating the database.");
        }
    }

    app.Run();
}
catch (Exception ex)
{
    Log.Fatal(ex, "Host terminated unexpectedly");
    return 1;
}
finally
{
    Log.CloseAndFlush();
}

return 0;